package controllers

import (
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"net/http"
	"personnel-management/dao/mysql"
	"personnel-management/logic"
	"personnel-management/models"
	"personnel-management/pkg/jwt"
	"strconv"
	"strings"
)

//  SignUpHandler注册
func SignUpHandler(c *gin.Context) {
	// 1.获取请求参数 2.校验数据有效性
	var fo models.RegisterForm
	if err := c.ShouldBindJSON(&fo); err != nil {
		ResponseErrorWithMsg(c, CodeInvalidParams, err.Error())
		return
	}
	// 3.注册用户
	err := mysql.Register(&models.User{
		PhoneNumber: fo.PhoneNumber,
		UserName:    fo.UserName,
		Password:    fo.Password,
		Email:       fo.Email,
	})
	if errors.Is(err, mysql.ErrorUserExit) {
		ResponseError(c, CodeUserExist)
		return
	}
	if err != nil {
		zap.L().Error("mysql.Register() failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
		return
	}
	ResponseSuccess(c, nil)
}

//  LoginHandler登录
func LoginHandler(c *gin.Context) {
	// 1.获取请求参数 2.校验数据有效性
	var L models.LoginUser
	if err := c.ShouldBindJSON(&L); err != nil {
		zap.L().Error("invalid params", zap.Error(err))
		ResponseErrorWithMsg(c, CodeInvalidParams, err.Error())
		return
	}
	//用户登录
	if err := mysql.Login(&L); err != nil {
		zap.L().Error("mysql.Login(&u) failed", zap.Error(err))
		ResponseError(c, CodeInvalidPassword)
		return
	}
	// 生成Token
	aToken, rToken, _ := jwt.GenToken(L.UserName)
	ResponseSuccess(c, gin.H{
		"accessToken":  aToken,
		"refreshToken": rToken,
		"userID":       L.UserID,
		"username":     L.UserName,
	})
}

//   RefreshTokenHandler刷新token
func RefreshTokenHandler(c *gin.Context) {
	rt := c.Query("refresh_token")
	// 客户端携带Token有三种方式 1.放在请求头 2.放在请求体 3.放在URI
	// 这里假设Token放在Header的Authorization中，并使用Bearer开头
	// 这里的具体实现方式要依据你的实际业务情况决定
	authHeader := c.Request.Header.Get("Authorization")
	if authHeader == "" {
		ResponseErrorWithMsg(c, CodeInvalidToken, "请求头缺少Auth Token")
		c.Abort()
		return
	}
	// 按空格分割
	parts := strings.SplitN(authHeader, " ", 2)
	if !(len(parts) == 2 && parts[0] == "Bearer") {
		ResponseErrorWithMsg(c, CodeInvalidToken, "Token格式不对")
		c.Abort()
		return
	}
	aToken, rToken, err := jwt.RefreshToken(parts[1], rt)
	fmt.Println("sadasdasd", err)
	c.JSON(http.StatusOK, gin.H{
		"access_token":  aToken,
		"refresh_token": rToken,
	})
}

//UserList  查看用户列表
func UserList(c *gin.Context) {
	//查询到所有的用户
	data, err := logic.GetUserList()
	if err != nil {
		zap.L().Error("mysql.GetUserList() failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
		return
	}
	ResponseSuccess(c, data)
}

func UserMessage(c *gin.Context) {
	// 获取作者Name，当前请求的UserName
	userName, err := getCurrentUserName(c)
	if err != nil {
		zap.L().Error("GetCurrentUserName() failed", zap.Error(err))
		ResponseError(c, CodeNotLogin)
		return
	}
	data, err := logic.GetUserMessage(userName)
	if err != nil {
		zap.L().Error("mysql.GetUserList() failed", zap.Error(err))
		ResponseError(c, CodeServerBusy)
		return
	}
	ResponseSuccess(c, data)
}

func UpdateUserMessage(c *gin.Context) {
	//1.获取博客ID
	idStr := c.Param("userid") //获取URL参数
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		ResponseError(c, CodeInvalidParams)
		return
	}
	var user models.User
	if err := c.ShouldBindJSON(&user); err != nil {
		ResponseErrorWithMsg(c, CodeInvalidParams, err.Error())
		return
	}
	// 获取作者Name，当前请求的UserName
	userName, err := getCurrentUserName(c)
	if err != nil {
		zap.L().Error("GetCurrentUserName() failed", zap.Error(err))
		ResponseError(c, CodeNotLogin)
		return
	}
	//2.根据name 获取用户详情
	err = logic.UpdateUserDetail(id, userName, &user)
	if err != nil {
		zap.L().Error("mysql.UpdateUserDetail() failed", zap.Error(err))
		ResponseError(c, CodeUserExist)
		return
	}
	ResponseSuccess(c, nil)
}

//删除用户
func DeleteUser(c *gin.Context) {
	//1.获取博客ID
	idStr := c.PostForm("userid") //获取URL参数
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		ResponseError(c, CodeInvalidParams)
		return
	}
	//2.根据name 获取用户详情
	err = logic.DeleteUserDetail(id)
	if err != nil {
		zap.L().Error("mysql.DeleteUserDetail() failed", zap.Error(err))
		ResponseError(c, CodeUserExist)
		return
	}
	ResponseSuccess(c, nil)
}
